/**
 * 面试列表页
 */
import React, { useState, useEffect, useMemo, useRef, useCallback } from 'react';
import useSharedSocket from '@/pages/Recruitment/Interview/hooks/useSharedSocket';
import { history, withRouter, connect } from 'umi';
import { Form, Select, Button, message, Spin, ConfigProvider } from 'antd';
import { useRequest, defaultFormatResult } from '@/hooks';
import { BottomAction } from '@/components';
import { PageContainer } from '@/molecules';
import pageTabUtil from '@/utils/pageTabUtil';
import isEmpty from 'lodash/isEmpty';
import isCurrentPageActived from './utils/isCurrentPageActived';
import WEBSOCKET_TYPES from './utils/WEBSOCKET_TYPES';
import { InterviewerInfo, TitleControl } from '../components';
import { CustomAddV2, AssessFrom, ADD_PREPARATION_PATH } from '../containers';
import styles from './Preparation.less';
import { deleteQuestion, getTalentMessage, getInterviewPrepare, submitInterview, saveQuestion } from '../service';

const formItemLayout = {
    labelCol: {},
    wrapperCol: {}
};

const { userCode } = localStorage.getItem('user') ? JSON.parse(localStorage.getItem('user')) : {};

// 总数据

const { Option } = Select;
const Preparation = ({ activedInterviewPageList, form, location }) => {
    const currentHref = useRef(window.location.href);
    const showMessage = useRef(false);
    const inputRef = useRef(); // 用于获取正在编辑的问题，对应input的ref
    const { query, pathname } = location;
    const { candidateId, arrangeId } = query;
    const [isInterviewing, setIsInterviewing] = useState(true);
    const { getFieldDecorator, setFieldsValue, getFieldValue } = form;
    const [chooseEvaluateForms, setChooseEvaluateForms] = useState([]);
    const [autoSaveLoading, setAutoSaveLoading] = useState(false);
    const tableRef = useRef();
    const getKeyArray = (item, evaluateFormInsts) => {
        const res = evaluateFormInsts.filter(x => x.formId === item.id);
        const selectKeys = res[0]?.formItems.map(x => x.itemId);
        const { id, ...others } = item;
        return {
            selectKeys,
            formId: id,
            ...others
        };
    };

    const { data: talentData = {}, loading: talentLoading } = useRequest(() => getTalentMessage(candidateId), {
        ...defaultFormatResult
    });

    const { data: interviewData = {}, loading: interviewLoading } = useRequest(() => getInterviewPrepare(arrangeId), {
        // refreshDeps: [action],
        ...defaultFormatResult
    });

    const {
        evaluateForms = [],
        evaluateFormInsts = [],
        othersInterviewQuestions = [],
        selfInterviewQuestions = [],
        interviewEmployees = [],
        interviewArrange = {}
    } = interviewData;

    useEffect(() => {
        if (evaluateFormInsts) {
            setChooseEvaluateForms(evaluateForms.filter(x => new Set(evaluateFormInsts.map(_ => _.formId)).has(x.id)));
        }
    }, [JSON.stringify(evaluateFormInsts)]);
    useEffect(() => {
        const { employeeCode } = localStorage.getItem('user') ? JSON.parse(localStorage.getItem('user')) : {};
        const isExist = interviewEmployees.some(item => item.employeeCode === employeeCode);
        if (interviewEmployees.length && !isExist) {
            message.error('您不是当前面试的面试官！');
            history.goBack();
        }
    }, [interviewEmployees]);
    useEffect(() => {
        if (showMessage.current && window.location.href === currentHref.current) {
            message.warning('您正在面试，不可同时编辑面试准备的内容');
            showMessage.current = false;
        }
    }, [window.location.href]);
    useEffect(() => {
        // 首次打开的时候，判断是否需要出现不可编辑提示。
        if (activedInterviewPageList.includes(Number(arrangeId))) {
            message.warning('您正在面试，不可同时编辑面试准备的内容');
        }
    }, []);
    const getChildren = React.useCallback(
        () =>
            evaluateForms.map(x => (
                <Option key={x.id} value={x.id.toString()}>
                    {x.formName}
                </Option>
            )),
        [evaluateForms]
    );
    const handleChange = value => {
        const newData = evaluateForms.filter(x => new Set(value).has(x.id.toString()));
        setChooseEvaluateForms(newData);
        form.setFieldsValue({});
    };
    // 根据后端提交表单需要 转换form获取的value数据格式
    const parseValue = source => {
        const data = Object.keys(source);
        const res = [];
        data.forEach(item => {
            if (item.startsWith('recruitEvaluateForm')) {
                res.push(source[item]);
                // delete source[item];
            }
        });
        return res.map(item => {
            const { selectKeys, ...other } = item;
            return {
                ...other,
                formItems: item.formItems
                    .filter(x => new Set(item.selectKeys).has(x.id))
                    .map(t => {
                        const { id, ...otherT } = t;
                        return {
                            ...otherT,
                            itemId: t.id
                        };
                    })
            };
        });
    };

    const getInitialValue = () => [
        ...selfInterviewQuestions.map(x => ({
            ...x,
            sort: 0,
            edit: false,
            quesType: 'self'
        })),
        ...othersInterviewQuestions.map(x => ({
            ...x,
            sort: 0,
            edit: false,
            quesType: 'other'
        }))
    ];

    /**
     * 弹出问题更新对应的提示
     * @param {Array} data 除本人外，其它面试官的自定义问题
     * @param {Number} newQuestionNum 新增问题数目
     */
    const showQuestionUpdateNotice = (data, newQuestionNum) => {
        const isPageActived = isCurrentPageActived(currentHref.current);
        if (!(data instanceof Array)) {
            return;
        }
        let nextFormList = (getFieldValue('interviewQuestions') || []).slice(); // 复制当前的自定义问题，包含自身+其它面试官
        const selfFormList = nextFormList.filter(item => item.quesType === 'self'); // 过滤出本人的自定义问题数组
        data.forEach((item, index) => {
            const { id: newId, createUserName, question: newQuestion } = item || {};
            const oldIndex = nextFormList.findIndex(old => old.id === newId);
            const selfFormLen = selfFormList.length;
            // 新增的问题
            if (oldIndex === -1) {
                const len = selfFormLen + index + 1;
                // 如果有未保存的新增问题，需要去掉末尾的最后一个
                if (isPageActived) {
                    message.warning(`${createUserName} 新增了面试问题 ${len - newQuestionNum}`);
                }
            } else {
                // 原本已存在的问题，这里需要判断问题是否被编辑，只需要判断question字段
                const old = nextFormList[oldIndex] || {};
                const { question: oldQuestion } = old;
                if (newQuestion !== oldQuestion) {
                    if (isPageActived) {
                        message.warning(`${createUserName} 更新了面试问题 ${oldIndex + 1}`);
                    }
                }
                // if (selfFormLen + index !== oldIndex) {
                //     message.warning(`${createUserName} 更新了面试问题 ${oldIndex + 1} 的顺序`);
                // }
            }
        });
        // 被删除的问题
        const removedArr = [];
        nextFormList = nextFormList.filter((old, index) => {
            const isRemoved = old.quesType === 'self' || data.findIndex(current => current.id === old.id) !== -1; // 是否是自己的问题，或是否为已存在的问题
            if (!isRemoved) {
                removedArr.push({
                    number: index + 1,
                    createUserName: old.createUserName
                });
            }
            return isRemoved;
        });
        removedArr.forEach(item => {
            if (isPageActived) {
                message.warning(`${item.createUserName} 删除了面试问题 ${item.number}`);
            }
        });
    };

    /**
     * 从服务器获取自定义问题
     */
    const getQuestion = async (showNotice = true) => {
        setAutoSaveLoading(true);
        const nextFormList = (getFieldValue('interviewQuestions') || []).slice();
        console.log('获取其它用户的自定义问题：', nextFormList);
        const editingList = nextFormList.filter(item => item.edit); // 过滤出正在编辑的条目
        console.log('=============editingList================>', JSON.stringify(editingList));
        if (editingList.length && inputRef.current) {
            console.log('========inputRef.current===============>', inputRef.current.refs.value);
            editingList[0].question = inputRef.current.state.value;
        }
        const result = await getInterviewPrepare(arrangeId);
        console.log('======自动保存后，获取数据=====>', result.data);
        // set form Data
        let resultModify = [
            ...result.data.selfInterviewQuestions.map(x => ({
                ...x,
                sort: 0,
                edit: false,
                quesType: 'self'
            })),
            ...result.data.othersInterviewQuestions.map(x => ({
                ...x,
                sort: 0,
                edit: false,
                quesType: 'other'
            }))
        ];
        // 排除掉已打开面试页面 + 有空白输入框的情况，避免 form报警 + 无提交按钮的错误情况。
        let newQuestionNum = 0; // 新增问题数目，根据是否有Id判断
        if (editingList.length && !activedInterviewPageList.includes(Number(arrangeId))) {
            if (editingList[0].id) {
                const temp = resultModify.find(item => item.id === editingList[0].id);
                if (temp) {
                    temp.question = editingList[0].question;
                    temp.edit = true;
                }
            } else {
                newQuestionNum = 1;
                resultModify = [...resultModify, ...editingList];
            }
        }
        if (showNotice) {
            // 需要在将新问题赋值给form前，查找新老数据的差异
            showQuestionUpdateNotice(result.data.othersInterviewQuestions, newQuestionNum);
        }
        setFieldsValue({
            interviewQuestions: resultModify
        });
        setAutoSaveLoading(false);
    };

    useEffect(() => {
        // 监听面试页面是否已打开
        if (activedInterviewPageList.includes(Number(arrangeId))) {
            // 面试页面已打开
            setIsInterviewing(true);
            if (isInterviewing === false) {
                showMessage.current = true; // 从可编辑变为不可编辑，才允许出现提示
            }
            const nextFormList = (getFieldValue('interviewQuestions') || []).slice();
            const editingList = nextFormList.filter(item => item.edit); // 过滤出正在编辑的条目
            if (editingList.length) {
                getQuestion();
            }
        } else {
            setIsInterviewing(false);
            showMessage.current = false;
        }
    }, [activedInterviewPageList.length]);

    const sharedEventHandler = res => {
        const msgBody = JSON.parse(res?.msg?.body);
        console.log('面试准备页收到报文：', msgBody);
        if (msgBody.type === WEBSOCKET_TYPES.SHARED_UPDATE_QUESTION) {
            if (msgBody.data.userCode === userCode && !msgBody.data.isRECPage) {
                // 过滤自己在面试准备页面发送的报文
            } else {
                // 非本人发送 or 本人在面试记录页面发送
                getQuestion();
            }
        }
    };

    const [sendUpdateQuestionMsg] = useSharedSocket(
        userCode,
        `sharedChannel${arrangeId}`,
        `jms.topic.shared${arrangeId}`,
        sharedEventHandler
    );

    /**
     * 在websocket中广播问题更新报文
     */
    const broadcastUpdateMsg = () => {
        sendUpdateQuestionMsg(false);
    };

    const handleCancel = () => {
        pageTabUtil.goBack();
    };

    /**
     *
     */
    const handleSubmit = () => {
        form.validateFields({ force: true }, async (err, values) => {
            console.log('=====>提交', values);
            console.log('=========>chooseEvaluateForms', chooseEvaluateForms);
            if (!err) {
                const { interviewQuestions = [] } = values;
                if (!chooseEvaluateForms.length && !interviewQuestions.length) {
                    message.error('面试问题与能力评估表至少有一个不能为空！');
                    if (!interviewQuestions.length) getQuestion(); // 最后一个问题删不掉，此时需要重新获取问题数据
                    return;
                }
                const recruitEvaluateForm = chooseEvaluateForms.length ? parseValue(values) : [];
                const res = await submitInterview({
                    arrangeId,
                    rankCode: talentData.rankCode,
                    candidateId,
                    interviewQuestions: interviewQuestions.map(item => ({
                        id: item.id,
                        question: item.question
                    })),
                    recruitEvaluateForm
                });
                if (res.code === 10000) {
                    pageTabUtil.goBack();
                } else {
                    message.error(res.msg);
                }
            }
        });
    };

    /**
     * blur时，自动保存自定义问题
     * type 0 新增 or 编辑，1 删除
     */
    const handleAutoSave = useCallback(
        (obj, type) => {
            console.log('handleAutoSave', obj, type);
            form.validateFields(['interviewQuestions'], async (err, values) => {
                console.log('=====>提交', values);
                console.log('=========>chooseEvaluateForms', chooseEvaluateForms);
                if (!err) {
                    const { interviewQuestions = [] } = values;
                    if (!chooseEvaluateForms.length && !interviewQuestions.length) {
                        message.error('面试问题与能力评估表至少有一个不能为空！');
                        if (!interviewQuestions.length) getQuestion(); // 最后一个问题删不掉，此时需要重新获取问题数据
                        return;
                    }
                    let param = {
                        arrangeId,
                        ...obj
                    };
                    if (!param.id) {
                        Reflect.deleteProperty(param, 'id');
                    }
                    if (type === 1 && param.id) {
                        param = param.id;
                    } else if (type === 1 && !param.id) {
                        return;
                    }
                    const requestFunc = type === 0 ? saveQuestion : deleteQuestion;
                    const res = await requestFunc(param);
                    if (res.code === 10000) {
                        // 自动保存时，需要更新本页面数据
                        getQuestion();
                        broadcastUpdateMsg();
                    } else {
                        message.error(res.msg);
                    }
                }
            });
        },
        [arrangeId, form, chooseEvaluateForms]
    );

    /**
     * 第二次进入
     */
    const secondAddition = useMemo(() => {
        const flag =
            pathname === ADD_PREPARATION_PATH && (selfInterviewQuestions?.length > 0 || evaluateFormInsts?.length > 0);
        return flag;
    }, [selfInterviewQuestions, evaluateFormInsts, pathname, ADD_PREPARATION_PATH]);

    // 状态流转，任一面试官提交面试记录后，stateChanged = true
    const stateChanged = useMemo(() => {
        const flag = !isEmpty(interviewArrange) && interviewArrange.interviewStatus !== 2;
        return flag;
    }, [interviewArrange]);

    // 编辑按钮被点击时，此表示改变
    const [editable, setEditable] = useState(false);

    // 是否展示浏览态
    const disabled = useMemo(() => stateChanged || (secondAddition && !editable) || isInterviewing, [
        secondAddition,
        stateChanged,
        editable,
        isInterviewing
    ]);

    // 是否展示问题
    const questionShow = useMemo(() => {
        if (disabled && !selfInterviewQuestions?.length && !othersInterviewQuestions?.length) {
            return false;
        }
        return true;
    }, [disabled, selfInterviewQuestions, othersInterviewQuestions]);

    // 是否展示能力评估
    const evaluateShow = useMemo(() => {
        if (disabled && !evaluateFormInsts?.length) {
            return false;
        }
        return true;
    }, [disabled, evaluateFormInsts]);

    const bottomAction = useMemo(() => {
        if (isEmpty(interviewData) || stateChanged || isInterviewing) {
            return null;
        }
        if (secondAddition && !editable) {
            return (
                <BottomAction>
                    <Button type="primary" onClick={() => setEditable(true)} className={styles.bigBtn}>
                        编辑
                    </Button>
                </BottomAction>
            );
        }
        return (
            <BottomAction>
                <Button loading={autoSaveLoading} type="primary" onClick={handleSubmit} className={styles.bigBtn}>
                    提交
                </Button>
            </BottomAction>
        );
    }, [stateChanged, secondAddition, editable, setEditable, handleSubmit, handleCancel, interviewData]);

    const titleRender = useCallback(() => {
        console.log('titleRender');
        return (
            <div className={styles.titleText}>
                面试问题
                <div className={styles.subTitle}>完成编辑后，答复将同步展示给其他面试官</div>
            </div>
        );
    }, []);

    return (
        <PageContainer>
            <div className={styles.mainPrepareInterviewInfo}>
                {/* 面试者基础信息卡片 */}

                <InterviewerInfo dataSource={talentData} loading={talentLoading} />
                <Spin spinning={interviewLoading}>
                    <Form layout="inline">
                        {questionShow && (
                            <TitleControl style={styles.higherTitle} titleRender={titleRender} title="面试问题">
                                <Form.Item label="">
                                    {getFieldDecorator('interviewQuestions', {
                                        initialValue:
                                            othersInterviewQuestions.length > 0 || selfInterviewQuestions.length > 0
                                                ? getInitialValue()
                                                : [{ question: '', sort: '', edit: true, id: '', quesType: 'self' }],
                                        validateTrigger: 'onSubmit', // 设置进行表单验证的时机为onSubmit
                                        rules: [
                                            {
                                                validator(_, value, callback) {
                                                    console.log('自定义问题的校验数据', value);
                                                    // eslint-disable-next-line no-restricted-syntax
                                                    for (const item of value || []) {
                                                        if (item.edit) {
                                                            callback('请完成面试问题编辑！');
                                                            return;
                                                        }
                                                    }
                                                    callback();
                                                }
                                            }
                                        ]
                                    })(
                                        <CustomAddV2
                                            inputRef={inputRef}
                                            handleAutoSave={handleAutoSave}
                                            form={form}
                                            disabled={disabled}
                                            loading={interviewLoading || autoSaveLoading}
                                            interviewLoading={interviewLoading}
                                        />
                                    )}
                                </Form.Item>
                            </TitleControl>
                        )}
                        {evaluateShow && (
                            <TitleControl title="能力评估表">
                                <div>
                                    <ConfigProvider getPopupContainer={trigger => tableRef.current || trigger}>
                                        <Form.Item label="面试评估表" {...formItemLayout}>
                                            {getFieldDecorator('check', {
                                                initialValue:
                                                    evaluateFormInsts.length > 0 ||
                                                    othersInterviewQuestions.length > 0 ||
                                                    selfInterviewQuestions.length > 0
                                                        ? evaluateFormInsts.map(x => x.formId.toString())
                                                        : []
                                            })(
                                                <Select
                                                    disabled={disabled}
                                                    mode="tags"
                                                    style={{ width: '630px', display: 'inline-block' }}
                                                    // tokenSeparators={[',']}
                                                    onChange={handleChange}
                                                    placeholder="请选择评估表"
                                                >
                                                    {getChildren()}
                                                </Select>
                                            )}
                                        </Form.Item>
                                    </ConfigProvider>
                                </div>
                                {chooseEvaluateForms.map(item => (
                                    <div key={item.id}>
                                        <Form.Item label="" required {...formItemLayout}>
                                            {getFieldDecorator(`recruitEvaluateForm${item.id}`, {
                                                initialValue:
                                                    evaluateFormInsts.length > 0 ||
                                                    othersInterviewQuestions.length > 0 ||
                                                    selfInterviewQuestions.length > 0
                                                        ? getKeyArray(item, evaluateFormInsts)
                                                        : { ...item, formId: item.id },
                                                validateTrigger: 'onSubmit',
                                                rules: [
                                                    {
                                                        validator(_, value, callback) {
                                                            console.log('自定义能力评估表校验', value);
                                                            // eslint-disable-next-line no-restricted-syntax
                                                            if (!value?.selectKeys || !value?.selectKeys?.length) {
                                                                message.error('请选择评估项！');
                                                                callback('请选择评估项！');
                                                                return;
                                                            }
                                                            callback();
                                                        }
                                                    }
                                                ]
                                            })(
                                                <AssessFrom
                                                    form={form}
                                                    loading={interviewLoading}
                                                    settings={{ checkDisabled: disabled, isPrepared: true }}
                                                />
                                            )}
                                        </Form.Item>
                                    </div>
                                ))}
                            </TitleControl>
                        )}
                    </Form>
                </Spin>
            </div>
            {bottomAction}
        </PageContainer>
    );
};

export default connect(({ interviewREC }) => ({
    activedInterviewPageList: interviewREC.activedInterviewPageList
}))(Form.create()(withRouter(Preparation)));
